package com.siteseat.crudeq.client;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.type.TypeReference;

import com.siteseat.common.json.JacksonMapper;
import com.siteseat.common.misc.FileHelper;

/**
 *
 */
public class ClientProfile {

  private static final TypeReference<ClientProfile> JSON_MAP_TYPE = new TypeReference<ClientProfile>() {};
  
  private Map<Integer,QueueHistory> receiveHistory = new HashMap<Integer,QueueHistory>();
  
  private int connectTimeoutByMilliseconds = 60 * 1000;
  
  private String serverHost = "change_me";
  
  private int serverPort = 40577;
  
  private String userName = "change_me";
  
  private String password = "change_me";
  
  private String clientId;
  
  private String language = "en_US";
  
  private File jsonFile; 
    
  /**
   * 
   *
   *
   * @param file
   */
  private ClientProfile( File file ) {
    this.jsonFile = file;
  }
  
  /**
   * 
   *
   *
   */
  private ClientProfile() {
    this.jsonFile = null;
  }
  
  /**
   *
   * @param jsonFileResource
   * @return
   * @throws IOException
   */
  public static ClientProfile load( File file, boolean createIfNotExistsOrEmpty ) throws IOException {    
    if( createIfNotExistsOrEmpty ) {
      if( FileHelper.createFileIfNotExists( file ) ) {
        ClientProfile r = new ClientProfile( file );
        r.save( file );
      }
    }
    
    InputStream ins = new FileInputStream( file );
    try {
      ClientProfile r = JacksonMapper.MAPPER.readValue( ins, JSON_MAP_TYPE );
      r.jsonFile = file;
      return r;
    } finally {
      IOUtils.closeQuietly( ins );
    }
  }
  
  /**
   *
   * @param jsonFile
   * @throws IOException
   */
  public void save() throws IOException {
    save( this.jsonFile );
  }

  /**
   *
   * @param jsonFile
   * @throws IOException
   */
  public void save( File file ) throws IOException {
    this.jsonFile = file;
    
    OutputStream ous = new FileOutputStream( file, false );
    try {
      save( ous );
    } finally {
      IOUtils.closeQuietly( ous );
    }
  }
 
 /**
  * 
  *
  * @param ous
  * @throws IOException
  */
 public void save( OutputStream ous ) throws IOException {
   String data = JacksonMapper.MAPPER.defaultPrettyPrintingWriter().writeValueAsString( this );
   IOUtils.write( data, ous, "utf-8" );
 }
  
  
  /**
   * Gets the userName
   *
   * @return the userName
   */
  public String getUserName() {
    return userName;
  }


  /**
   * Sets the userName
   *
   * @param userName the userName to set
   */
  public void setUserName( String userName ) {
    this.userName = userName;
  }


  /**
   * Gets the password
   *
   * @return the password
   */
  public String getPassword() {
    return password;
  }


  /**
   * Sets the password
   *
   * @param password the password to set
   */
  public void setPassword( String password ) {
    this.password = password;
  }


  /**
   * Gets the clientId
   *
   * @return the clientId
   */
  public String getClientId() {
    if( StringUtils.isBlank( this.clientId ) ) {
      this.clientId = UUID.randomUUID().toString();
    }
    return clientId;
  }


  /**
   * Sets the clientId
   *
   * @param clientId the clientId to set
   */
  public void setClientId( String clientId ) {
    this.clientId = clientId;
  }


  /**
   * Gets the language
   *
   * @return the language
   */
  public String getLanguage() {
    return language;
  }


  /**
   * Sets the language
   *
   * @param language the language to set
   */
  public void setLanguage( String language ) {
    this.language = language;
  }


  /**
   * Gets the connectTimeoutByMilliseconds
   *
   * @return the connectTimeoutByMilliseconds
   */
  public int getConnectTimeoutByMilliseconds() {
    return connectTimeoutByMilliseconds;
  }



  /**
   * Sets the connectTimeoutByMilliseconds
   *
   * @param connectTimeoutByMilliseconds the connectTimeoutByMilliseconds to set
   */
  public void setConnectTimeoutByMilliseconds( int connectTimeoutByMilliseconds ) {
    this.connectTimeoutByMilliseconds = connectTimeoutByMilliseconds;
  }

  /**
   * Gets the receiveHistory
   *
   * @return the receiveHistory
   */
  public Map<Integer, QueueHistory> getReceiveHistory() {
    return receiveHistory;
  }

  /**
   * Sets the receiveHistory
   *
   * @param receiveHistory the receiveHistory to set
   */
  public void setReceiveHistory( Map<Integer, QueueHistory> receiveHistory ) {
    this.receiveHistory = receiveHistory;
  }

  /**
   * Gets the serverHost
   *
   * @return the serverHost
   */
  public String getServerHost() {
    return serverHost;
  }

  /**
   * Sets the serverHost
   *
   * @param serverHost the serverHost to set
   */
  public void setServerHost( String serverHost ) {
    this.serverHost = serverHost;
  }

  /**
   * Gets the serverPort
   *
   * @return the serverPort
   */
  public int getServerPort() {
    return serverPort;
  }

  /**
   * Sets the serverPort
   *
   * @param serverPort the serverPort to set
   */
  public void setServerPort( int serverPort ) {
    this.serverPort = serverPort;
  }

}
